home *** CD-ROM | disk | FTP | other *** search
- /********************************************************/
- /* Markers Module for SkyView */
- /* */
- /* (c)1992 N P Hawkes */
- /* */
- /* Displays markers at regular RA & Dec intervals */
- /********************************************************/
-
- #include "menu.h"
- #include "dbox.h"
- #include "bbc.h"
- #include "wimpt.h"
- #include "dbox.h"
- #include "string.h"
- #include "event.h"
-
- #include "sv_header.h"
- #include "markers.h"
- #include "radec.h"
-
- #include <stdio.h>
- #include <stdlib.h>
-
- /********************************************************/
- /* Constants */
- /********************************************************/
- #define DISP_NAME "Markers" /* Entry in Display menu.*/
- #define SEL_NAME "Marker..." /* Entry in Select menu. */
- #define SELBOX_NAME "MarkersSel" /* Name of Sel dbox. */
-
- #define HORALT (REAL)0.0044 /* Altitude of horizon.*/
-
- /* No. of Declination values (starting at -90 deg.): */
- #define NDEC 19
-
- /*No. of RA values at each Dec value (starting at 0 hr):*/
- static int nra[NDEC] =
- {1, 12, 12, 12, 12, 12, 12, 12, 12, 24,
- 12, 12, 12, 12, 12, 12, 12, 12, 1};
-
- /* Constants relating to Selection dialogue box. */
- enum {
- box_cancel = -1, /* Response cancelling the dbox. */
- sel_ok = 0, /* OK button. */
- sel_cancel, /* Cancel button. */
- dec_dn, /* Button to decrease declination. */
- dec_up, /* Button to increase declination. */
- dec_field, /* Field No. for declination. */
- ra_dn, /* Button to decrease rt ascension. */
- ra_up, /* Button to increase rt ascension. */
- ra_field /* Field No. for rt ascension. */
- };
-
- /********************************************************/
- /* New types of variable. */
- /********************************************************/
- /* Structure describing one marker. */
- typedef struct {
- REAL ra; /* Right ascension (radians). */
- REAL dec; /* Declination (radians). */
- int horiz_id; /* id in Horiz window. */
- int vert_id; /* id in Vert window. */
- int hi; /* Markers in range lo (inclusive) */
- int lo; /* to hi (exclusive) all have */
- /* declination 'dec'. */
- } markerstr;
-
- /********************************************************/
- /* Global Variables */
- /********************************************************/
- static BOOL display_flag = FALSE; /* 'Enabled' flag. */
- static BOOL list_valid = FALSE; /* TRUE if list valid*/
- static int moduleid; /* Module ID. */
-
- static int marker_count = 0; /* Total no. of markers. */
- static markerstr *marker_data; /* Ptr to main data store*/
-
- static dbox d_sel; /* Selection dbox. */
- static int sel_id = 97; /* ID of most recent sel- */
- /* ection made via dbox. */
-
- /********************************************************/
- /* Function Prototypes */
- /********************************************************/
- static void markers_buildfn(void);
- static BOOL markers_displayfn(BOOL *enabptr);
- static os_error *markers_plotfn(int x, int y, int id);
- static void markers_infofn(int id);
- static void markers_selectfn(selectfn_reasoncode reason);
- static int selectionbox(void);
- static void selection_details(void);
- static void selbox_load(int id);
- static int selbox_buttons(int start_id);
- static int find_lower_dec(int old_id, REAL target);
- static int find_higher_dec(int old_id, REAL target);
- static int find_lower_ra(int old_id);
- static int find_higher_ra(int old_id);
- static int ra_search(int lo, int hi, REAL target);
-
- /********************************************************/
- /* Initialisation Function */
- /********************************************************/
- BOOL markers_initfn(int moduleno, modulestr *markers)
- {
- int i, j;
- int first;
- REAL ddec; /* Interval of Declination (radians). */
- REAL dra; /* Interval of Rt Ascension (radians).*/
- int marker_id = 0; /* id number of marker. */
-
- /* Record the module number of this module. */
- moduleid = moduleno;
-
-
- /* Allocate memory for main data store. */
-
- /* Calculate how many markers there are. */
- for (i=0; i<NDEC; i++)
- marker_count += nra[i];
- /* Allocate memory. Quit if allocation fails. */
- marker_data = calloc(marker_count, sizeof(markerstr));
- if (marker_data == NULL) return FALSE;
-
- /* Generate the data array. */
-
- /* Calculate declination interval in radians. */
- if (NDEC > 1)
- ddec = PI/(NDEC - 1);
-
- /* Calculate data for all markers at each dec. value. */
- for (i=0; i<NDEC; i++)
- {
- /* Remember first id number at this dec. */
- first = marker_id;
- /* Find interval of right ascension. */
- dra = (REAL)2.0*PI/nra[i];
- /* Deal with each ra value in turn. */
- for (j=0; j<nra[i]; j++)
- {
- marker_data[marker_id].ra = j * dra;
- marker_data[marker_id].dec = i * ddec - PIby2;
- marker_data[marker_id].lo = first;
- marker_data[marker_id].hi = first + nra[i];
- marker_id++;
- }
- }
-
-
- /* Fill in the fields of the modulestr. */
- markers->buildfn = markers_buildfn;
- markers->selectfn = markers_selectfn;
- markers->dispfn = markers_displayfn;
- markers->infofn = markers_infofn;
- markers->initial = display_flag;
- markers->display_entry = DISP_NAME;
- markers->display_menu = NULL;
- markers->select_entry = SEL_NAME;
- markers->select_menu = NULL;
-
- return TRUE;
- }
-
- /********************************************************/
- /* List-Building Function */
- /********************************************************/
- static void markers_buildfn(void)
- {
- int i;
- plotobj marker;
-
- /* Bounding box of plotting symbol, relative to */
- /* position of symbol: */
- static wimp_box size = {-10, -10, 10, 10};
-
- /* If module is currently disabled, ignore call to list-*/
- /* building function, and set flag to indicate that */
- /* module does not have valid data in the plotting list.*/
- if (!display_flag)
- {
- list_valid = FALSE;
- return;
- }
-
- /* If module is currently enabled, build plotting list */
- /* and set flag to indicate module has valid data. */
- list_valid = TRUE;
-
- /* For each marker in turn: */
- for (i=0; i<marker_count; i++)
- {
-
- /* Build plotobj. */
- marker.id = i;
- marker.module = moduleid;
- marker.plotfn = markers_plotfn;
- radec_altaz(marker_data[i].ra, marker_data[i].dec, &ob_data, ob_data.sid,
- &marker.alt, &marker.azim);
- marker.size = size;
-
- /* Offer this to the main program. */
- addobj(marker, &marker_data[i].horiz_id, &marker_data[i].vert_id);
-
- }
-
- return;
- }
-
-
-
- /********************************************************/
- /* Object-Selecting Function */
- /********************************************************/
- static void markers_selectfn(selectfn_reasoncode reason)
- {
- int marker_id;
-
- switch (reason)
- {
- case new_selection:
- /* Using dialogue box, determine which marker is */
- /* to be selected. A return of -1 indicates */
- /* dialogue was cancelled. */
- marker_id = selectionbox();
- if (marker_id == -1)
- {
- selection.selected_OK = FALSE;
- return;
- }
- /* Valid selection has been made. */
- /* Remember id of selected marker for next time, */
- /* and give the id number to the main program. */
- sel_id = marker_id;
- selection.id = marker_id;
- /* Flag the selection as successful. */
- selection.selected_OK = TRUE;
- /* Fill in Selection details for requested marker.*/
- selection_details();
- break;
-
- case window_selection:
- /* A selection has been made by clicking in a */
- /* window. */
- case recalculate_data:
- /* Observer details have changed, and plotting */
- /* lists have been rebuilt. */
- /* */
- /* In both cases, the ID of the marker is already */
- /* in selection.id */
- selection_details();
- break;
-
- case timeonly_recalculate:
- /* As recalculate_data, but only the time of day */
- /* (and possibly the direction of view - this is */
- /* is of no interest) have changed. */
- /* This simplifies the calculation. */
- marker_id = selection.id;
- selection.horiz_id = marker_data[marker_id].horiz_id;
- selection.vert_id = marker_data[marker_id].vert_id;
- /* Decide if it can be seen now. */
- selection.now = selection.horiz_id != NOWHERE || \
- selection.vert_id != NOWHERE;
- break;
-
- case sel_info_request:
- /* Write info into text buffer. */
- {
- REAL rah; /* Right Ascension in hours. */
- REAL decd; /* Declination in degrees. */
-
- marker_id = selection.id;
-
- rah = marker_data[marker_id].ra * (REAL)12.0 / PI;
- decd = marker_data[marker_id].dec / CONV;
-
- sprintf(infoptr,"%s%s%.1f%s%s%.1f%s",
- "Marker\n",
- "RA ", (double)rah, " hours\n",
- "Dec ",(double)decd,"°");
- }
- break;
-
- default:
- /* Unknown option. Do nothing. */
- break;
-
- }
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to obtain id number of marker to be selected*/
- /* by means of a dialogue box. */
- /* Returns -1 if dialogue is cancelled. */
- /*------------------------------------------------------*/
- static int selectionbox(void)
- {
- int result; /*Result of dialogue. */
-
- /* Ensure menu has gone, create dbox, load it with info */
- /* and put it on display. (If not already done.) */
- if (!dbox_persisting)
- {
- event_clear_current_menu();
- d_sel = dbox_new(SELBOX_NAME);
- if (d_sel == NULL) return -1;
- selbox_load(sel_id);
- dbox_show(d_sel);
- }
-
- /* Deal with button clicks until user clicks OK, or */
- /* clicks Cancel with left hand mouse button, or clicks */
- /* outside dbox. Result is chosen id, or -1 if cancelled*/
- result = selbox_buttons(sel_id);
-
- /* Delete dbox if it is not required to persist. */
- if (!dbox_persisting) dbox_dispose(&d_sel);
-
- /* Return the chosen value. */
- return result;
- }
-
- /*------------------------------------------------------*/
- /* Function to load info from marker No. 'id' into */
- /* selection dbox */
- /*------------------------------------------------------*/
- static void selbox_load(int id)
- {
-
- REAL rah; /* Right Ascension in hours. */
- REAL decd; /* Declination in degrees. */
- char numbuf[32];
-
- rah = marker_data[id].ra * (REAL)12.0 / PI;
- decd = marker_data[id].dec / CONV;
-
- /* Get RA of marker into string form. */
- sprintf(numbuf, "%.1f hours", (double)rah);
- /* Write RA into ra field of dbox. */
- dbox_setfield(d_sel, ra_field, numbuf);
-
- /* Get Dec of marker into string form. */
- sprintf(numbuf, "%+.1f°", (double)decd);
- /* Write Dec into dec field of dbox. */
- dbox_setfield(d_sel, dec_field, numbuf);
-
- return;
- }
-
- /*------------------------------------------------------*/
- /* Function to deal with button clicks in Selection box.*/
- /*------------------------------------------------------*/
- static int selbox_buttons(int start_id)
- {
- /* start_id is ID number on show initially. */
-
- /* new_id is ID number currently on show. */
- int new_id = start_id;
-
- int response; /* Latest button No. clicked by user.*/
- REAL ra_target; /* RA of marker is to be as close to */
- /* this as possible. */
-
- ra_target = marker_data[start_id].ra;
-
- /* Loop until user clicks on OK, or on Cancel with left-*/
- /* hand mouse button, or closes dbox with a 'harmful */
- /* event' (eg clicking outside dbox). */
- for (;;)
- {
-
- /* Get field number of latest click. */
- response = dbox_fillin(d_sel);
-
- /* Take appropriate action. */
- switch (response) {
-
- case box_cancel:
- /* dbox cancelled. Close it and return -1. */
- dbox_persisting = FALSE;
- return -1;
-
- case sel_ok:
- /* Return current id number. Retain dbox if click*/
- /* was with Adjust. */
- dbox_persisting = dbox_persist();
- return new_id;
-
- case sel_cancel:
- /* If normal click, close dbox and return -1. */
- /* If Adjust, reload initial id and keep looping. */
- if (dbox_persist())
- {
- new_id = start_id;
- ra_target = marker_data[start_id].ra;
- selbox_load(new_id);
- }
- else
- {
- dbox_persisting = FALSE;
- return -1;
- }
- break;
-
- case dec_dn:
- /* Decrease declination. Find marker with next */
- /* lower dec, and RA as close to ra_target as poss*/
- new_id = find_lower_dec(new_id, ra_target);
- /* Load new info into dbox. */
- selbox_load(new_id);
- break;
-
- case dec_up:
- /* Increase declination. Find marker with next */
- /* higher dec, and RA as close to ra_target as */
- /* possible. */
- new_id = find_higher_dec(new_id, ra_target);
- /* Load new info into dbox. */
- selbox_load(new_id);
- break;
-
- case ra_dn:
- /* Decrease Right Ascension. */
- new_id = find_lower_ra(new_id);
- /* Update ra_target. */
- ra_target = marker_data[new_id].ra;
- /* Load new info into dbox. */
- selbox_load(new_id);
- break;
-
- case ra_up:
- /* Increase Right Ascension. */
- new_id = find_higher_ra(new_id);
- /* Update ra_target. */
- ra_target = marker_data[new_id].ra;
- /* Load new info into dbox. */
- selbox_load(new_id);
- break;
-
- }
- }
- }
-
- /*------------------------------------------------------*/
- /* Functions to find new marker id which most closely */
- /* fits the change requested by the user. */
- /*------------------------------------------------------*/
- static int find_lower_dec(int old_id, REAL target)
- {
- /* Search for id having 'dec' one increment lower than */
- /* current marker, and 'ra' as close as poss. to target.*/
-
- int old_lo; /* First id with the current value of dec.*/
- int dum_id; /* Used to obtain search range. */
- int new_lo; /* Start of range to be searched for ra. */
- int new_hi; /* End of search range (exclusive). */
-
- old_lo = marker_data[old_id].lo;
-
- /* Establish range of ids to be searched. */
- /* Obtain an id which has the desired declination. */
- /* Cycle round to top of dec range if necessary. */
- dum_id = (old_lo > 0 ? old_lo - 1 : marker_count - 1);
- /* Use this id to get range of ids with desired dec. */
- new_lo = marker_data[dum_id].lo;
- new_hi = marker_data[dum_id].hi;
-
- /* Return id within this range which has closest ra. */
- return ra_search(new_lo, new_hi, target);
- }
-
- static int ra_search(int lo, int hi, REAL target)
- {
- REAL min_error = (REAL)2.0*PI;
- REAL error;
- int id;
- int nearest = 0;
-
- for (id=lo; id<hi; id++)
- {
- error = marker_data[id].ra - target;
- if (error < (REAL)0.0) error = -error;
- if (error < min_error)
- {
- min_error = error;
- nearest = id;
- }
- }
- return nearest;
- }
-
- static int find_higher_dec(int old_id, REAL target)
- {
- /* Search for id having 'dec' one increment higher than */
- /* current marker, and 'ra' as close as poss. to target.*/
-
- int old_hi; /* Last id with the current value of dec. */
- int dum_id; /* Used to obtain search range. */
- int new_lo; /* Start of range to be searched for ra. */
- int new_hi; /* End of search range (exclusive). */
-
- old_hi = marker_data[old_id].hi;
-
- /* Establish range of ids to be searched. */
- /* Obtain an id which has the desired declination. */
- /* Cycle round to botttom of dec range if necessary. */
- dum_id = (old_hi >= marker_count ? 0 : old_hi);
- /* Use this id to get range of ids with desired dec. */
- new_lo = marker_data[dum_id].lo;
- new_hi = marker_data[dum_id].hi;
-
- /* Return id within this range which has closest ra. */
- return ra_search(new_lo, new_hi, target);
-
- }
-
- static int find_lower_ra(int old_id)
- {
- int new_id = old_id - 1;
-
- if (new_id < marker_data[old_id].lo)
- new_id = marker_data[old_id].hi - 1;
-
- return new_id;
- }
-
- static int find_higher_ra(int old_id)
- {
- int new_id = old_id + 1;
-
- if (new_id >= marker_data[old_id].hi)
- new_id = marker_data[old_id].lo;
-
- return new_id;
- }
-
-
- /*------------------------------------------------------*/
- /* Function to fill in selection details of selected */
- /* marker (viewing directions and times for rising, */
- /* setting, culminating etc). */
- /*------------------------------------------------------*/
- static void selection_details(void)
- {
- double ch; /* cos of hour angle at horizon. */
- BOOL riset; /* Whether object rises & sets or not. */
- BOOL culmin; /* Whether object culminates or not. */
-
- /* ID number of marker is in selection.id */
- int id = selection.id;
-
- /* Record window IDs of selected marker. */
- selection.horiz_id = marker_data[id].horiz_id;
- selection.vert_id = marker_data[id].vert_id;
-
- /* Find out if it can be seen now. */
- selection.now = selection.horiz_id != NOWHERE || \
- selection.vert_id != NOWHERE;
-
- /* Find out if marker rises, sets or culminates today. */
- /* (After setting effective altitude of horizon.) */
- radec_sethoriz(HORALT);
-
- radec_phenomena(marker_data[id].ra, marker_data[id].dec, &ob_data,
- &ch, &riset, &culmin);
- selection.rising = riset;
- selection.setting = riset;
- selection.culminating = culmin;
-
- /* Fill in details for each phenomenon which occurs. */
-
- if (selection.rising)
- radec_rise_details(
- marker_data[id].ra, marker_data[id].dec, &ob_data, ch,
- &selection.rise_azim,
- &selection.rise_hour,
- &selection.rise_min);
-
- if (selection.setting)
- radec_set_details(
- marker_data[id].ra, marker_data[id].dec, &ob_data, ch,
- &selection.set_azim,
- &selection.set_hour,
- &selection.set_min);
-
- if (selection.culminating)
- radec_cul_details(
- marker_data[id].ra, marker_data[id].dec, &ob_data,
- &selection.cul_alt,
- &selection.cul_azim,
- &selection.cul_hour,
- &selection.cul_min);
-
- return;
- }
-
- /********************************************************/
- /* Display Function */
- /********************************************************/
- static BOOL markers_displayfn(BOOL *enabptr)
- {
- /* Toggle Enable/Disable flag. */
- display_flag = !display_flag;
-
- /* Inform main program of new status. */
- *enabptr = display_flag;
-
- /* If module is now enabled, but does not have valid */
- /* data in the plotting list, call the list-building fn.*/
- if (display_flag && !list_valid)
- markers_buildfn();
-
- /* Windows will always need updating. */
- return TRUE;
- }
-
-
- /********************************************************/
- /* Plotting Function */
- /********************************************************/
- static os_error *markers_plotfn(int x, int y, int id)
- {
- os_error *errptr;
-
- /* Set foreground graphics colour to Wimp colour 10 */
- errptr = sv_setcolour(10);
- if (errptr != NULL) return errptr;
-
- /* Draw a suitable symbol at the given coordinates. */
- errptr = bbc_move(x-8, y);
- if (errptr != NULL) return errptr;
- errptr = bbc_draw(x+8, y);
- if (errptr != NULL) return errptr;
- errptr = bbc_move(x, y-8);
- if (errptr != NULL) return errptr;
-
- return bbc_draw(x, y+8);
- }
-
-
- /********************************************************/
- /* Info Function */
- /********************************************************/
- static void markers_infofn(int id)
- {
- REAL rah; /* Right Ascension in hours. */
- REAL decd; /* Declination in degrees. */
-
- rah = marker_data[id].ra * (REAL)12.0 / PI;
- decd = marker_data[id].dec / CONV;
-
- sprintf(infoptr,"%s%s%.1f%s%s%.1f%s",
- "Marker\n",
- "RA ", (double)rah, " hours\n",
- "Dec ",(double)decd,"°");
-
- return;
- }
-